package com.sunshine.wrongquestionset.activity.main

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.text.Html
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity

import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.bumptech.glide.Glide
import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.textfield.TextInputEditText

import com.sunshine.wrongquestionset.R
import com.sunshine.wrongquestionset.activity.add_question.AddQuestionActivity
import com.sunshine.wrongquestionset.activity.exercise.ExerciseActivity
import com.sunshine.wrongquestionset.activity.question.QuestionActivity
import com.sunshine.wrongquestionset.callback.OnClickListener
import com.sunshine.wrongquestionset.callback.OnRefreshListener
import com.sunshine.wrongquestionset.callback.QuestionOptionsListener
import com.sunshine.wrongquestionset.room.entity.QuestionEntity
import com.sunshine.wrongquestionset.room.entity.QuestionInfoEntity
import com.sunshine.wrongquestionset.room.entity.SubjectEntity
import com.sunshine.wrongquestionset.room.entity.WrongQuestionBean
import com.sunshine.wrongquestionset.utils.AnalyzerUtils
import com.sunshine.wrongquestionset.view.QuestionContentBottomSheetDialog
import com.wanglu.photoviewerlibrary.PhotoViewer
import com.zzhoujay.markdown.MarkDown
import com.zzhoujay.richtext.ImageHolder
import com.zzhoujay.richtext.RichText
import com.zzhoujay.richtext.RichType
import com.zzhoujay.richtext.callback.OnImageClickListener
import es.dmoral.toasty.Toasty
import kotlinx.android.synthetic.main.activity_add_question_expend.*
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.fragment_home.recyclerView
import kotlinx.android.synthetic.main.fragment_home.textView_title_content
import java.util.*
import kotlin.collections.ArrayList

class HomeFragment : Fragment() {

    private lateinit var viewModel: MainViewModel
    private lateinit var userId: String

    private var quicklyExerciseList: List<QuestionEntity>? = null
    private var quicklyExerciseSubjectName: String? = null

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_home, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(requireActivity().application)).get(MainViewModel::class.java)

        quicklyExercise()

        //如果当前用户是空，代表需要刷新
        (requireActivity() as MainActivity).getLoginUserId(object : OnRefreshListener<String>() {
            override fun onUpdate(obj: String) {
                super.onUpdate(obj)
                userId = obj
                initSubject()
                initEverydayOneExercise()
            }
        })

        //添加题目
        fab_add_question.setOnClickListener {
            startActivity(Intent(requireActivity(), AddQuestionActivity::class.java))
        }

        include_quickly_exercise.setOnClickListener {
            startQuickExercise()
        }
    }

    /**
     * 智能练习
     */
    private fun quicklyExercise() {
        (requireActivity() as MainActivity).getLoginUserId(object : OnRefreshListener<String>() {
            @SuppressLint("SetTextI18n")
            override fun onUpdate(obj: String) {
                super.onUpdate(obj)

//                if (hasExercise) return

                //将题目按照科目分类
                val questionMap = HashMap<Int, java.util.ArrayList<QuestionEntity>>()

                //获取题目，一次获取后移除观察者
                var getQuestionObserver: Observer<List<QuestionEntity>?>? = null
                val questionListLiveData = viewModel.getQuestion(obj)
                getQuestionObserver = Observer {questionList ->
                    if (questionList.isNullOrEmpty()) {
                        include_quickly_exercise
                            .findViewById<TextView>(R.id.textView_quickly_exercise_sub)
                            .text = getString(R.string.quickly_exercise_sub)
                        quicklyExerciseList = null
                        quicklyExerciseSubjectName = null
                    }
                    else {
                        questionList.forEach { questionEntity ->
                            //如果哈希表中没有这个，就新建
                            if (questionMap[questionEntity.subjectId] == null) {
                                questionMap[questionEntity.subjectId] = java.util.ArrayList()
                                questionMap[questionEntity.subjectId]!!.add(questionEntity)
                            } else {
                                if (!questionMap[questionEntity.subjectId]!!.contains(questionEntity))
                                    questionMap[questionEntity.subjectId]!!.add(questionEntity)
                            }
                        }

                        //分析确定最需要练习的科目
                        val quicklyExerciseBean = AnalyzerUtils.getBestQuicklyExerciseSubject(questionMap)

                        if (quicklyExerciseBean == null || quicklyExerciseBean.questionList.isNullOrEmpty()) {
                            include_quickly_exercise
                                .findViewById<TextView>(R.id.textView_quickly_exercise_sub)
                                .text = getString(R.string.quickly_exercise_sub)
                            quicklyExerciseList = null
                            quicklyExerciseSubjectName = null
                        }
                        else {
                            var getSubjectObserver: Observer<SubjectEntity?>? = null
                            val subjectLiveData = viewModel.getSubjectById(quicklyExerciseBean.subjectId)
                            getSubjectObserver = Observer {
                                quicklyExerciseList = quicklyExerciseBean.questionList
                                quicklyExerciseSubjectName = it?.name

                                include_quickly_exercise
                                    .findViewById<TextView>(R.id.textView_quickly_exercise_sub)
                                    .text = "今天为你推荐了${quicklyExerciseList?.size}道“${quicklyExerciseSubjectName}”题目"
                            }

                            subjectLiveData.observe(viewLifecycleOwner, getSubjectObserver)
                            //end 获取科目
                        }
                    }
                }

                questionListLiveData.observe(viewLifecycleOwner, getQuestionObserver)
                //end 获取题目

//                viewModel.getQuestion(obj).observe(this@MainActivity, Observer {questionList ->
//                    if (hasExercise) return@Observer
//
//                    if (questionList.isNullOrEmpty()) quicklyExerciseFail()
//                    else {
//                        questionList.forEach { questionEntity ->
//                            //如果哈希表中没有这个，就新建
//                            if (questionMap[questionEntity.subjectId] == null) {
//                                questionMap[questionEntity.subjectId] = ArrayList()
//                                questionMap[questionEntity.subjectId]!!.add(questionEntity)
//                            } else {
//                                questionMap[questionEntity.subjectId]!!.add(questionEntity)
//                            }
//                        }
//
//                        //分析确定最需要练习的科目
//                        val quicklyExerciseBean = AnalyzerUtils.getBestQuicklyExerciseSubject(questionMap)
//
//                        //启动
//                        if (quicklyExerciseBean == null || quicklyExerciseBean.questionList.isNullOrEmpty()) quicklyExerciseFail()
//                        else {
//                            viewModel.getSubjectById(quicklyExerciseBean.subjectId).observe(this@MainActivity, Observer {
//                                if (hasExercise) return@Observer
//
//                                ExerciseActivity.subjectName = it?.name ?: "未知科目"
//                                ExerciseActivity.setQuestionList(quicklyExerciseBean.questionList)
//                                startActivity(Intent(this@MainActivity, ExerciseActivity::class.java))
//                                hasExercise = true
//                            })
//                        }
//                    }
//                })
            }
        })
    }

    private fun startQuickExercise() {
        if (quicklyExerciseList.isNullOrEmpty()) {
            quicklyExerciseFail()
        } else {
            ExerciseActivity.subjectName = quicklyExerciseSubjectName ?: "未知科目"
            ExerciseActivity.setQuestionList(quicklyExerciseList)
            startActivity(Intent(requireActivity(), ExerciseActivity::class.java))
        }
    }

    /**
     * 智能练习失败
     */
    private fun quicklyExerciseFail() {
        Toasty.success(requireContext(), getString(R.string.quickly_exercise_fail)).show()
    }


    /**
     * 初始化界面上的科目
     */
    private fun initSubject() {
        viewModel.getSubject(userId).observe(viewLifecycleOwner, Observer {subjectList ->
            recyclerView.adapter = SubjectRecyclerAdapter(
                subjectList as ArrayList<SubjectEntity>,
                viewLifecycleOwner,
                viewModel,
                object : OnClickListener {
                    override fun onClick(position: Int) {
                        addSubject(userId)
                    }

                    override fun onLongClick(position: Int) {
                        val builder = MaterialAlertDialogBuilder(requireContext())

                        var dialog: AlertDialog? = null

                        builder.apply {
                            val menuView = LayoutInflater.from(requireContext()).inflate(R.layout.view_subject_menu, null, false)
                            val show: MaterialButton = menuView.findViewById(R.id.button_show)
                            val edit: MaterialButton = menuView.findViewById(R.id.button_edit)
                            val toDelete: MaterialButton = menuView.findViewById(R.id.button_to_delete)

                            show.setOnClickListener {
                                val intent = Intent(requireContext(), QuestionActivity::class.java)
                                intent.putExtra("type", QuestionActivity.TYPE_SUBJECT)
                                intent.putExtra("subjectId", subjectList[position].id)
                                startActivity(intent)
                                dialog?.cancel()
                            }
                            edit.setOnClickListener {
                                dialog?.cancel()
                                editSubject(subjectList[position], userId)
                            }
                            toDelete.setOnClickListener {
                                val builder1 = MaterialAlertDialogBuilder(requireContext())
                                builder1.apply {
                                    setTitle(getString(R.string.warning_title))
                                    setMessage(Html.fromHtml(getString(R.string.warning_message)))
                                    setPositiveButton(getString(R.string.delete_cancel)) {_, _ ->

                                    }
                                    setNegativeButton(getString(R.string.delete)) {_, _ ->
                                        try {
                                            if (subjectList.size <= 1) {
                                                Snackbar.make(home_root, getString(R.string.delete_subject_fail), Snackbar.LENGTH_SHORT).show()
                                            } else {
                                                viewModel.toDelete(subjectList[position])
                                                Snackbar.make(home_root, getString(R.string.delete_success), Snackbar.LENGTH_SHORT).show()
                                            }
                                        }catch (e: Exception) {
                                            //虽然用捕获异常的方式不大好，但是方便...
                                            Snackbar.make(home_root, getString(R.string.delete_subject_fail_1), Snackbar.LENGTH_SHORT).show()
                                        }

                                        dialog?.cancel()
                                    }
                                }
                                builder1.create().show()
                            }
                            setView(menuView)
                        }
                        dialog = builder.create()
                        dialog.show()
                    }

                }
            )
        })
    }

    /**
     * 添加信息
     */
    private fun addSubject(loginUserId: String) {
        editSubject(null, loginUserId)
    }

    /**
     * 修改科目信息
     * @param subjectEntity 科目实体
     */
    private fun editSubject(
        subjectEntity: SubjectEntity?,
        loginUserId: String
    ) {
        val builder = MaterialAlertDialogBuilder(requireContext())
        builder.apply {
            val view = LayoutInflater.from(requireContext()).inflate(R.layout.view_add_subject, null, false)
            val nameEditText: TextInputEditText = view.findViewById(R.id.edit_add_subject)

            nameEditText.setText(subjectEntity?.name)

            setView(view)
            setTitle(if (subjectEntity == null) getString(R.string.add_subject) else getString(R.string.edit_subject))
            setPositiveButton("确定") {_, _ ->
                val name = nameEditText.text?.toString()
                if (name.isNullOrBlank()) {
                    Snackbar.make(home_root, getString(R.string.subject_error), Snackbar.LENGTH_SHORT).show()
                } else {
                    //添加模式
                    if (subjectEntity == null) {
                        viewModel.addSubject(loginUserId, name)
                        Snackbar.make(home_root, getString(R.string.add_subject_success), Snackbar.LENGTH_SHORT).show()
                    }
                    //编辑模式
                    else {
                        subjectEntity.name = name
                        viewModel.updateSubject(subjectEntity)
                        Snackbar.make(home_root, getString(R.string.edit_subject_success), Snackbar.LENGTH_SHORT).show()
                    }
                }
            }
        }
        builder.create().show()
    }

    /**
     * 初始化每日一题的题目
     */
    @SuppressLint("SetTextI18n")
    private fun initEverydayOneExercise() {
        var everydayQuestion: QuestionEntity
        val questionLiveData = viewModel.getQuestion(userId)

        var questionObserver: Observer<List<QuestionEntity>?>? = null
        questionObserver = Observer {
            //为空给出提示
            if (it.isNullOrEmpty()) {
                textView_title_content.text = getString(R.string.no_question)
                imageView_show_answer.setOnClickListener(null)
            } else {
                val calendar = Calendar.getInstance()
                //选取一个题目，这里采用一年中第几天取模
                val position = calendar.get(Calendar.DAY_OF_YEAR) % it.size

                everydayQuestion = it[position]

                var titlePath = everydayQuestion.titlePath

                if (titlePath.contains(Regex("!\\[.*]\\(.*\\)"))) {
                    titlePath = "内含图片，请点击右上角问号按钮进行查看"
                }

                RichText
                    .from(titlePath)
                    .type(RichType.markdown)
                    .scaleType(ImageHolder.ScaleType.fit_auto)
                    .imageClick(object : OnImageClickListener {
                        override fun imageClicked(imageUrls: MutableList<String>?, position: Int) {
                            if (imageUrls.isNullOrEmpty()) return
                            PhotoViewer
                                .setClickSingleImg(imageUrls[position], ImageView(requireContext()))   //因为本框架不参与加载图片，所以还是要写回调方法
                                .setShowImageViewInterface(object : PhotoViewer.ShowImageViewInterface {
                                    override fun show(iv: ImageView, url: String) {
                                        Glide.with(iv.context).load(url).into(iv)
                                    }
                                })
                                .start(this@HomeFragment)
                        }
                    })
                    .into(textView_title_content)

//                textView_title_content.post {
//                    Thread {
//                        val spanned = MarkDown.fromMarkdown(everydayQuestion.titlePath.replace("\n", "\n\n"), { source ->
//                            try {
//                                //主线程执行，效果不是很好
//                                val drawable = Drawable.createFromPath(source)
//                                drawable?.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
//                                drawable
//                            }catch (e: Exception) {
//                                //Snackbar.make(add_question_expend_root, getString(R.string.load_image_fail_2), Snackbar.LENGTH_SHORT).show()
//                                null
//                            }
//                        }, textView_title_content)
//
//                        textView_title_content.post {
//                            textView_title_content.text = spanned
//                        }
//                    }.start()
//                }

                imageView_show_answer.setOnClickListener {
                    //练习记录熟悉程度变化折线图
                    val questionInfoByQuestionIdLiveData = viewModel.getQuestionInfoByQuestionId(everydayQuestion.id)
                    var questionInfoByQuestionIdObserver: Observer<List<QuestionInfoEntity>?>? = null
                    questionInfoByQuestionIdObserver = Observer { questionInfoList ->
                        val wrongQuestionBeanByQuestionIdLiveData = viewModel.getWrongQuestionBeanByQuestionId(everydayQuestion.id)
                        var wrongQuestionBeanByQuestionIdObserver: Observer<List<WrongQuestionBean>?>? = null
                        wrongQuestionBeanByQuestionIdObserver = Observer {wrongQuestionBeanList ->
                            val questionFamiliarityBean =
                                AnalyzerUtils.analyzerQuestionFamiliarity(questionInfoList, 10)

                            QuestionContentBottomSheetDialog.show(
                                requireActivity() as AppCompatActivity,
                                everydayQuestion.titlePath,
                                everydayQuestion.answerPath,
                                getString(R.string.from_everyday_exercise),
                                questionFamiliarityBean,
                                wrongQuestionBeanList,
                                callback = object : QuestionOptionsListener {
                                    override fun onDelete() {
                                        //删除题目
                                        val builder = MaterialAlertDialogBuilder(requireContext())
                                        builder.apply {
                                            setTitle(context.getString(R.string.warning_title))
                                            setMessage(Html.fromHtml(context.getString(R.string.delete_question_warning)))
                                            setPositiveButton("我再想想") {_, _ ->}
                                            setNegativeButton("删除") {_, _ ->
                                                viewModel.deleteQuestion(everydayQuestion)
                                                Toasty.success(context, context.getString(R.string.delete_success)).show()
                                            }
                                        }
                                        builder.create().show()
                                    }

                                    override fun onEdit() {
                                        AddQuestionActivity.editQuestionEntity = everydayQuestion
                                        val intent = Intent(requireActivity(), AddQuestionActivity::class.java)
                                        intent.putExtra("type", AddQuestionActivity.TYPE_EDIT)
                                        startActivity(intent)
                                    }
                                }
                            )
                            wrongQuestionBeanByQuestionIdLiveData.removeObserver(wrongQuestionBeanByQuestionIdObserver!!)
                        }
                        //错题列表
                        wrongQuestionBeanByQuestionIdLiveData.observe(viewLifecycleOwner, wrongQuestionBeanByQuestionIdObserver)
                        questionInfoByQuestionIdLiveData.removeObserver(questionInfoByQuestionIdObserver!!)
                    }
                    questionInfoByQuestionIdLiveData.observe(viewLifecycleOwner, questionInfoByQuestionIdObserver)
                }
            }
        questionLiveData.removeObserver(questionObserver!!)
        }
        questionLiveData.observe(viewLifecycleOwner, questionObserver)
    }
}